package com.gitee.wsl.compose.chart.xy.bar.group.model

import com.gitee.wsl.compose.chart.ChartAdapter
import com.gitee.wsl.compose.chart.xy.bar.model.BarEntry
import com.gitee.wsl.compose.chart.xy.bar.model.BarPosition
import com.gitee.wsl.compose.chart.xy.bar.model.GroupedBarEntry


class EntryToGroupedEntryListAdapter<X, Y>(
    val data: List<BarEntry<X, Y>>
) : AbstractList<GroupedBarEntry<X, Y>>() {
    override val size: Int
        get() = data.size

    override fun get(index: Int): GroupedBarEntry<X, Y> {
        return EntryToGroupedBarEntryAdapter(data[index])
    }
}

internal class EntryToGroupedBarEntryAdapter<X, Y>(
     val entry: BarEntry<X, Y>
 ) : GroupedBarEntry<X, Y> {

    override val x: X = entry.x

    override val y: List<BarPosition<Y>>
        get() = object : AbstractList<BarPosition<Y>>() {
            override val size: Int = 1
            override fun get(index: Int): BarPosition<Y> = entry.y
        }
}

fun <X, Y> ChartAdapter.Companion.groupedBar(builder: GroupedBarAdapterBuilder<X, Y>.() -> Unit):List<GroupedBarEntry<X, Y>>{
    val mapElement: MutableMap<X,MutableList<BarPosition<Y>>> = mutableMapOf()
    object:GroupedBarAdapterBuilder<X, Y>{
        override fun grouped(
            x: X, yMin: Y, yMax: Y
        ) {
           mapElement.getOrPut(x) {mutableListOf()}.add(BarPosition(yMin, yMax))
        }
    }.builder()
    return mapElement.map{ GroupedBarEntry(it.key, it.value) }
}

interface GroupedBarAdapterBuilder<X, Y>{
    fun grouped(x: X, yMin: Y, yMax: Y)
}